#pragma once
#include <iostream>
#include <cstdio>
#include <string>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

//将NamedPipe封装成一个类，向外提供相关接口
const int default_fd = -1;
const int default_mode = 0666;
const std::string defalut_filename = "myfifo";


class NamedPipe
{
public:
    NamedPipe(std::string filename = defalut_filename):_filename(filename),_fd(default_fd)
    {
        //不能将命名管道的创建写在构造函数中，因为server端和client端不能同时创建命名管道
    }
    
    //创建命名管道
    bool Create()
    {
        int ret = mkfifo(_filename.c_str(),default_mode);
        if(ret == 0)
            return true;
        return false;
    }

    bool OpenForRead()
    {
        int ret = open(_filename.c_str(),O_RDONLY);
        if(ret < 0)
            return false;
        _fd = ret;
        return true;
    }

    int OpenForWrite()
    {
        int ret = open(_filename.c_str(),O_WRONLY);
        if(ret < 0)
            return false;
        _fd = ret;
        return true;
    }

    void Write()
    {
        while(true)
        {
            std::string buffer;
            std::cout << "Please Enter:" ;
            fsync(_fd);
            getline(std::cin,buffer);
            write(_fd,buffer.c_str(),buffer.size());
        }  
    }

    void Read()
    {
        while(true)
        {
            char buffer[128] = {0};
            int cnt = read(_fd,buffer,sizeof(buffer) - 1);
            if(cnt == 0)
                return;
            buffer[cnt] = {0};
            std::cout << "client say:" << buffer << std::endl;
        }
    }

    //关闭管道文件
    void Close()
    {
        close(_fd);
    }

    //删除管道文件
    void Remove()
    {
        unlink(_filename.c_str());
    }
    ~NamedPipe()
    {
        //析构同理
    }




private:
    std::string _filename;
    int _fd;
};